﻿using System ;
using System.Windows ;
using System.Windows.Interactivity ;
using System.Reflection ;
using System.Diagnostics ;

namespace OpenLightGroup.Common.Behaviors
    {
        //
        // If you want your Action to target elements other than its parent, extend your class
        // from TargetedTriggerAction instead of from TriggerAction
        //
        public class SetPropertyValueAction : TriggerAction<DependencyObject>
            {
                public SetPropertyValueAction ( )
                    {
                        // Insert code required on object creation below this point.
                    }

                public object TargetObject
                {
                    get
                        {
                            return this.GetValue( TargetObjectProperty ) ;
                        }
                    set
                        {
                            this.SetValue( TargetObjectProperty, value ) ;
                        }
                }

                // Using a DependencyProperty as the backing store for TargetObject.  This enables animation, styling, binding, etc...
                public static readonly DependencyProperty TargetObjectProperty =
                DependencyProperty.Register( "TargetObject", typeof(object), typeof(SetPropertyValueAction), new PropertyMetadata( null ) ) ;

                public string PropertyName
                {
                    get
                        {
                            return (string)this.GetValue( PropertyNameProperty ) ;
                        }
                    set
                        {
                            this.SetValue( PropertyNameProperty, value ) ;
                        }
                }

                // Using a DependencyProperty as the backing store for PropertyName.  This enables animation, styling, binding, etc...
                public static readonly DependencyProperty PropertyNameProperty =
                DependencyProperty.Register( "PropertyName", typeof(string), typeof(SetPropertyValueAction), new PropertyMetadata( null ) ) ;

                public object Value
                {
                    get
                        {
                            return this.GetValue( ValueProperty ) ;
                        }
                    set
                        {
                            this.SetValue( ValueProperty, value ) ;
                        }
                }

                // Using a DependencyProperty as the backing store for Value.  This enables animation, styling, binding, etc...
                public static readonly DependencyProperty ValueProperty =
                DependencyProperty.Register( "Value", typeof(object), typeof(SetPropertyValueAction), new PropertyMetadata( null ) ) ;

                protected override void Invoke ( object o )
                    {

                        PropertyInfo property = this.TargetObject.GetType( ).GetProperty( this.PropertyName ) ;

                        Type targetPropertyType = property.GetValue( this.TargetObject, null ).GetType( ) ;

                        if ( targetPropertyType is Object || targetPropertyType == this.Value.GetType( ) )
                        {
                            property.SetValue( this.TargetObject, this.Value, null ) ;

                        }
                        else
                        {
                            object convertedValue = null ;

                            try
                            {

                                convertedValue = Convert.ChangeType( this.Value, targetPropertyType, null ) ;
                                property.SetValue( this.TargetObject, convertedValue, null ) ;

                            }
                            catch (Exception ex)
                            {

                                Debug.WriteLine( "Could not convert value of type " + this.Value.GetType( ).ToString( ) + " to " + targetPropertyType.ToString( ) ) ;
                                Debug.WriteLine( ex.Message ) ;

                                //convertedValue = null;
                            }


                        }

                    }
            }
    }